#include "NetWork.h"

typedef struct Train_s{
    int length;
    char data[1000];
}Train;

int recvn(int sock_fd, void *buf, long total){
    char *p = (char *)buf;
    long cursize = 0;
    while(cursize < total){
        ssize_t sret = recv(sock_fd,p+cursize,total-cursize,0);
        if(sret == 0){
            return 1;
        }
        cursize += sret;
    }
    return 0;
}

int TcpInit(const char *IP, const char *port, SocketType type, int *socket_fd){
    *socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(*socket_fd, -1, "socket");
    int ret = 0;
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(port));
    addr.sin_addr.s_addr = inet_addr(IP);
    if(type == listen_type){
        int reuse = 1;
        ret = setsockopt(*socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
        ERROR_CHECK(ret, -1, "set socket opt");

        ret = bind(*socket_fd, (struct sockaddr *)&addr, sizeof(addr));
        ERROR_CHECK(ret, -1, "bind");

        listen(*socket_fd, 50);
    }else if(type == connect_type){
        ret = connect(*socket_fd, (struct sockaddr *)&addr, sizeof(addr));
        ERROR_CHECK(ret, -1, "connect");
    }
    return 0;
}

int Accept(const int listen_fd, int *net_fd){
    *net_fd = accept(listen_fd, NULL, NULL);
    return 0;
}

int SendTrain(const int net_fd, const char *buf){
    Train train;
    bzero(&train,sizeof(train));
    train.length = strlen(buf);
    memcpy(train.data, buf,train.length);
    int ret = send(net_fd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
    ERROR_CHECK(ret, -1, "send");
    return 0;
}

int RecvTrain(const int net_fd, char *buf){
    Train train;
    bzero(&train,sizeof(train));
    recvn(net_fd, &train.length, sizeof(train.length));
    recvn(net_fd, train.data, train.length);
    memcpy(buf,train.data,train.length);
    return 0;
}
/*
SendTrain与RecvTrain用例
    int test_pipe[2];
    socketpair(AF_LOCAL, SOCK_STREAM, 0, test_pipe);
    char buf1[1024] = {0};
    if(fork() != 0){
        char buf2[1024] = "123";
        memcpy(buf1, buf2, strlen(buf2));
        SendTrain(test_pipe[1], buf1);
        wait(NULL);
        exit(0);
    }
    RecvTrain(test_pipe[0], buf1);
    printf("%s\n", buf1);
*/


int EpollAdd(int epoll_fd, int fd, uint32_t events){
    struct epoll_event ev;
    ev.data.fd = fd;
    ev.events = events;
    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);

    return 0;
}

int EpollDel(int epoll_fd, int fd){
    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);

    return 0;
}

